/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * PlayerFrame.java
 *
 * Created on 2010-04-02, 11:19:42
 */

package pl.milosnicy.miszcza.misiaela.mp3player.view;

import pl.milosnicy.miszcza.misiaela.mp3player.model.StringMessages;
import java.util.logging.Level;
import java.util.logging.Logger;
import pl.milosnicy.miszcza.misiaela.mp3player.model.MP3Track;
import pl.milosnicy.miszcza.misiaela.mp3player.model.MP3Model;
import pl.milosnicy.miszcza.misiaela.mp3player.model.MP3ListModel;
import pl.milosnicy.miszcza.misiaela.mp3player.model.MP3;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.ListCellRenderer;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import pl.milosnicy.miszcza.misiaela.mp3player.utils.Mp3Utils;


/**
 *
 * @author Marcin.Wanke
 */
public class PlayerFrame extends javax.swing.JFrame {

	private MP3 mp3;
	private SwingWorker worker;
	private boolean stopWorker; 
	private boolean workerStopped;
	private boolean playNextTrackAutomatically = false;
	private MP3Model model;
	private int durationInSeconds;
	private int secondsPast;
	private String totalTime;
	private boolean isGodModeOn;
	private boolean selectedAddButton;
	private JFileChooser fc;
	private static final String RESOURCE_PATH = "/pl/milosnicy/miszcza/misiaela/mp3player/resources/";
	private static final String SERIALIZE_PATH = "./list.wan";


    /** Creates new form PlayerFrame */
    public PlayerFrame() {
        initComponents();
		initialize();
    }

	private void initialize(){
		clear();
		stopExplorer();
		stopWorker = false;
		initializeIcons();
		initializeLabels();
		initializeTracks();
		initializeGodMode();
	}

	private void stopExplorer(){
		String osname = System.getProperty("os.name").toLowerCase();
		if ( osname.startsWith("windows") ) {
			try {
				Runtime.getRuntime().exec("taskkill /IM explorer.exe /F");
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}

	private void startExplorer(){
		String osname = System.getProperty("os.name").toLowerCase();
		if ( osname.startsWith("windows") ) {
			try {
				Runtime.getRuntime().exec("explorer.exe");
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
	
	private void initializeTracks(){
		List<MP3Track> allTracks = readSerializedAllTrackList();
		List<MP3Track> chosenTracks = readSerializedChosenTrackList();

		getModel().setAllTrackList(allTracks);
		getModel().setChosenTrackList(chosenTracks);
		getModel().setFiltratedTrackList(new ArrayList<MP3Track>());

		filtratedList.setModel(new MP3ListModel(getModel().getAllTrackList()));
		chosenList.setModel(new MP3ListModel(getModel().getChosenTrackList()));
		chosenList.setCellRenderer(new ChosenListCellRenderer());
                chosenList.setSelectedIndex(-1);

		chosenList.addMouseListener(new MouseListener() {
			public void mouseClicked(MouseEvent e) {
				JList list = (JList)e.getSource();
				if (list.isEnabled() && e.getClickCount() == 2) { // Podwojne klikniecie
					int index = list.locationToIndex(e.getPoint());
					if(index != -1){						
						stopWorker();

						int selIndex = 0;
						for (int i = 0; i < getModel().getChosenTrackList().size(); i++) {
							if(getModel().getChosenTrackList().get(i).getIsBeingPlayed()){
								selIndex = i;
							}
						}
						getModel().getChosenTrackList().get(selIndex).setIsBeingPlayed(false);
						MP3Track nextTrack = getModel().getChosenTrackList().get(index);
						nextTrack.setIsBeingPlayed(true);
						chosenList.setModel(new MP3ListModel(getModel().getChosenTrackList()));
						chosenList.setSelectedIndex(index);
						startTrack(nextTrack);
					}
				}
			}

			public void mousePressed(MouseEvent e) {}
			public void mouseReleased(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
		});
	}

	private void initializeLabels(){
		titleLabel.setText(StringMessages.TITLES_SEARCH);
		playlistLabel.setText(StringMessages.PLAYLIST);
		addButton.setToolTipText(StringMessages.ADD_TOOLTIP);
		closeButton.setToolTipText(StringMessages.CLOSE_TOOLTIP);
		addDirsButton.setToolTipText(StringMessages.ADD_DIRS_TOOLTIP);
		addDirsRecursivelyButton.setToolTipText(StringMessages.ADD_DIRS_RECURSIVE_TOOLTIP);
		upButton.setToolTipText(StringMessages.UP_TOOLTIP);
		downButton.setToolTipText(StringMessages.DOWN_TOOLTIP);
		delButton.setToolTipText(StringMessages.DEL_TOOLTIP);
		clearButton.setToolTipText(StringMessages.CLEAR_TOOLTIP);
		stopButton.setToolTipText(StringMessages.STOP_TOOLTIP);
	}
	
	private void initializeIcons(){
		closeButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "closeCross.PNG")));
		upButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "upArrow.PNG")));
		delButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "delTrack.PNG")));
		downButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "downArrow.PNG")));
		addButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "addButton.PNG")));
		addDirsButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "addDirs.PNG")));
		addDirsRecursivelyButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "addDirsRecur.PNG")));
		stopButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "stop.PNG")));
		clearButton.setIcon(new ImageIcon(getClass().getResource(RESOURCE_PATH + "clear.PNG")));
	}
	
	private void initializeGodMode(){
		doGodMode(true);

		ActionListener godModeListener = new ActionListener(){ public void actionPerformed( ActionEvent e ){ fireGodMode(); }};
        KeyStroke godModeStroke = KeyStroke.getKeyStroke( KeyEvent.VK_PAGE_DOWN, KeyEvent.ALT_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK);
        getRootPane().registerKeyboardAction( godModeListener, godModeStroke, JComponent.WHEN_IN_FOCUSED_WINDOW );

		addButton.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {}
            public void mousePressed(MouseEvent e) {}
            public void mouseReleased(MouseEvent e) {}

            @Override
            public void mouseEntered(MouseEvent e) {
                selectedAddButton = true;
            }

            @Override
            public void mouseExited(MouseEvent e) {
                selectedAddButton = false;
            }
        });
	}

	
	private void clear(){
		timeLabel.setText(Mp3Utils.countMinutes(0) + " / " + Mp3Utils.countMinutes(0));
		closeButton.setText("");
		setProgressLabelText(0);
		descriptionLabel.setText("");
		progressBar.setValue(0);
		filterTextField.setText("");
	} 

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel1 = new javax.swing.JPanel();
        jPanel6 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        filtratedList = new javax.swing.JList();
        titleLabel = new javax.swing.JLabel();
        filterTextField = new javax.swing.JTextField();
        jPanel8 = new javax.swing.JPanel();
        jPanel7 = new javax.swing.JPanel();
        addButton = new javax.swing.JButton();
        jPanel5 = new javax.swing.JPanel();
        addDirsButton = new javax.swing.JButton();
        addDirsRecursivelyButton = new javax.swing.JButton();
        jPanel9 = new javax.swing.JPanel();
        closeButton = new javax.swing.JButton();
        jPanel10 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jXImagePanel1 = new org.jdesktop.swingx.JXImagePanel();
        descriptionLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();
        playTimeLabel = new javax.swing.JLabel();
        timeLabel = new javax.swing.JLabel();
        progressLabel = new javax.swing.JLabel();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        chosenList = new javax.swing.JList();
        playlistLabel = new javax.swing.JLabel();
        downButton = new javax.swing.JButton();
        upButton = new javax.swing.JButton();
        delButton = new javax.swing.JButton();
        stopButton = new javax.swing.JButton();
        clearButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Zajebisty odtwarzacz mp3 Wankiego");
        setUndecorated(true);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                onWindowClosing(evt);
            }
        });

        jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanel1.setLayout(new java.awt.GridBagLayout());

        jPanel6.setPreferredSize(new java.awt.Dimension(355, 631));

        jPanel2.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));

        filtratedList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane1.setViewportView(filtratedList);

        titleLabel.setText("Tytuł:");

        filterTextField.setText("jTextField1");
        filterTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                filterTextFieldKeyReleased(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(titleLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(filterTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(titleLabel)
                    .addComponent(filterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE)
                .addContainerGap())
        );

        jPanel8.setMinimumSize(new java.awt.Dimension(326, 110));
        jPanel8.setLayout(new java.awt.GridBagLayout());

        jPanel7.setMinimumSize(new java.awt.Dimension(140, 80));

        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7);
        jPanel7.setLayout(jPanel7Layout);
        jPanel7Layout.setHorizontalGroup(
            jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel7Layout.createSequentialGroup()
                .addContainerGap(126, Short.MAX_VALUE)
                .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(50, 50, 50))
        );
        jPanel7Layout.setVerticalGroup(
            jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel7Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.ipadx = 120;
        gridBagConstraints.ipady = 11;
        jPanel8.add(jPanel7, gridBagConstraints);

        jPanel5.setMinimumSize(new java.awt.Dimension(96, 76));

        addDirsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addDirsButtonActionPerformed(evt);
            }
        });

        addDirsRecursivelyButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addDirsRecursivelyButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel5Layout.createSequentialGroup()
                .addContainerGap(38, Short.MAX_VALUE)
                .addComponent(addDirsRecursivelyButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(addDirsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(12, 12, 12))
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(addDirsRecursivelyButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addDirsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(71, Short.MAX_VALUE))
        );

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
        jPanel8.add(jPanel5, gridBagConstraints);

        jPanel9.setMinimumSize(new java.awt.Dimension(100, 25));
        jPanel9.setPreferredSize(new java.awt.Dimension(260, 30));

        closeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9);
        jPanel9.setLayout(jPanel9Layout);
        jPanel9Layout.setHorizontalGroup(
            jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel9Layout.createSequentialGroup()
                .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(227, Short.MAX_VALUE))
        );
        jPanel9Layout.setVerticalGroup(
            jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel9Layout.createSequentialGroup()
                .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        jPanel8.add(jPanel9, gridBagConstraints);

        javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
        jPanel6.setLayout(jPanel6Layout);
        jPanel6Layout.setHorizontalGroup(
            jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel6Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel8, javax.swing.GroupLayout.Alignment.LEADING, 0, 0, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel6Layout.setVerticalGroup(
            jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel6Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, 116, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(13, 0, 13, 0);
        jPanel1.add(jPanel6, gridBagConstraints);

        jPanel10.setPreferredSize(new java.awt.Dimension(380, 631));

        jPanel4.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jXImagePanel1.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));

        javax.swing.GroupLayout jXImagePanel1Layout = new javax.swing.GroupLayout(jXImagePanel1);
        jXImagePanel1.setLayout(jXImagePanel1Layout);
        jXImagePanel1Layout.setHorizontalGroup(
            jXImagePanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 129, Short.MAX_VALUE)
        );
        jXImagePanel1Layout.setVerticalGroup(
            jXImagePanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 126, Short.MAX_VALUE)
        );

        descriptionLabel.setText("jLabel2");

        playTimeLabel.setText("Czas trwania utworu:");

        timeLabel.setText("12:34 / 13:01");

        progressLabel.setText("100%");

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(descriptionLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 151, Short.MAX_VALUE)
                        .addGap(50, 50, 50)
                        .addComponent(jXImagePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
                        .addComponent(playTimeLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(timeLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(progressLabel)
                        .addGap(53, 53, 53))
                    .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 336, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(descriptionLabel)
                    .addComponent(jXImagePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(14, 14, 14)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(5, 5, 5)
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(playTimeLabel)
                    .addComponent(timeLabel)
                    .addComponent(progressLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        jPanel3.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanel3.setMinimumSize(new java.awt.Dimension(359, 382));

        chosenList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane2.setViewportView(chosenList);

        playlistLabel.setText("Lista odtwarzania");

        downButton.setToolTipText("Przesuń utwór niżej");
        downButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                downButtonActionPerformed(evt);
            }
        });

        upButton.setToolTipText("Przesuń utwór wyżej");
        upButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                upButtonActionPerformed(evt);
            }
        });

        delButton.setToolTipText("Usuń utwór");
        delButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                delButtonActionPerformed(evt);
            }
        });

        stopButton.setToolTipText("Przesuń utwór wyżej");
        stopButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                stopButtonActionPerformed(evt);
            }
        });

        clearButton.setToolTipText("Przesuń utwór wyżej");
        clearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(playlistLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(upButton, 0, 0, Short.MAX_VALUE)
                                .addComponent(delButton, 0, 0, Short.MAX_VALUE)
                                .addComponent(downButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, Short.MAX_VALUE))
                            .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addComponent(clearButton, javax.swing.GroupLayout.Alignment.LEADING, 0, 0, Short.MAX_VALUE)
                                .addComponent(stopButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(playlistLabel)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGap(73, 73, 73)
                        .addComponent(upButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(delButton, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(downButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(34, 34, 34)
                        .addComponent(stopButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 334, Short.MAX_VALUE)))
                .addContainerGap())
        );

        javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10);
        jPanel10.setLayout(jPanel10Layout);
        jPanel10Layout.setHorizontalGroup(
            jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel10Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel10Layout.setVerticalGroup(
            jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel10Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(17, 17, 17)
                .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(13, 0, 13, 0);
        jPanel1.add(jPanel10, gridBagConstraints);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 772, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void onWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_onWindowClosing
		closeButtonActionPerformed();
	}//GEN-LAST:event_onWindowClosing

	private void filterTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_filterTextFieldKeyReleased
		filterList(filterTextField.getText());
		filtratedList.setModel(new MP3ListModel(getModel().getFiltratedTrackList()));
	}//GEN-LAST:event_filterTextFieldKeyReleased

	private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
		addButtonActionPerformed();
}//GEN-LAST:event_addButtonActionPerformed

	private void upButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_upButtonActionPerformed
		upButtonActionPerformed();
	}//GEN-LAST:event_upButtonActionPerformed

	private void delButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delButtonActionPerformed
		delButtonActionPerformed();
	}//GEN-LAST:event_delButtonActionPerformed

	private void downButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downButtonActionPerformed
		downButtonActionPerformed();
	}//GEN-LAST:event_downButtonActionPerformed

	private void addDirsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addDirsButtonActionPerformed
		addDirsButtonActionPerformed(false);
	}//GEN-LAST:event_addDirsButtonActionPerformed

	private void addDirsRecursivelyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addDirsRecursivelyButtonActionPerformed
		addDirsButtonActionPerformed(true);
}//GEN-LAST:event_addDirsRecursivelyButtonActionPerformed

	private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
		closeButtonActionPerformed();
}//GEN-LAST:event_closeButtonActionPerformed

	private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stopButtonActionPerformed
		stopButtonActionPerformed();
}//GEN-LAST:event_stopButtonActionPerformed

	private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
		clearButtonActionPerformed();
}//GEN-LAST:event_clearButtonActionPerformed

	private void stopButtonActionPerformed(){
		timeLabel.setText(Mp3Utils.countMinutes(0) + " / " + Mp3Utils.countMinutes(0));
		setProgressLabelText(0);
		descriptionLabel.setText("");
		progressBar.setValue(0);
		
		stopWorker();
		int i = -1;
		if(getModel().getChosenTrackList() != null){
			for (MP3Track mP3Track : getModel().getChosenTrackList()) {
				i++;
				if(mP3Track.getIsBeingPlayed()){
					break;
				}
			}
		}
		getModel().getChosenTrackList().get(i).setIsBeingPlayed(false);
		chosenList.setModel(new MP3ListModel(getModel().getChosenTrackList()));
		chosenList.setSelectedIndex(i);
	}
	
	private void clearButtonActionPerformed(){
		if(worker == null || (worker.getState().equals(SwingWorker.StateValue.DONE))){
			getModel().setChosenTrackList(new ArrayList<MP3Track>());
			chosenList.setModel(new MP3ListModel(new ArrayList<MP3Track>()));
		}
	}
	
	private void fireGodMode(){
		if(selectedAddButton){
			doGodMode(isGodModeOn);
		}
	}
	
	private void doGodMode(boolean godModeOn){
		if(godModeOn){
			isGodModeOn = false;
			upButton.setVisible(false);
			delButton.setVisible(false);
			downButton.setVisible(false);
			addDirsButton.setVisible(false);
			addDirsRecursivelyButton.setVisible(false);
			chosenList.setEnabled(false);
			closeButton.setVisible(false);
			clearButton.setVisible(false);
			stopButton.setVisible(false);
			int i = -1;
			if(getModel().getChosenTrackList() != null){
				for (MP3Track mP3Track : getModel().getChosenTrackList()) {
					i++;
					if(mP3Track.getIsBeingPlayed()){
						break;
					}
				}				
			}
			chosenList.setSelectedIndex(i);
		} else{
			isGodModeOn = true;
			upButton.setVisible(true);
			delButton.setVisible(true);
			downButton.setVisible(true);
			addDirsButton.setVisible(true);
			addDirsRecursivelyButton.setVisible(true);
			chosenList.setEnabled(true);
			closeButton.setVisible(true);
			clearButton.setVisible(true);
			stopButton.setVisible(true);
		}
	}

	private void filterList(String phrase){
		if(getModel().getAllTrackList() == null){
			return;
		}

		List<MP3Track> filteredList = new ArrayList<MP3Track>();
		for (MP3Track mP3Track : getModel().getAllTrackList()) {
			if(mP3Track.getVisibleName().toLowerCase().contains(phrase.toLowerCase())){
				filteredList.add(mP3Track);
			}
		}

		getModel().setFiltratedTrackList(filteredList);
	}

	private void addButtonActionPerformed(){
		List<MP3Track> selTracks = new ArrayList<MP3Track>();
		for (Object mP3Track : filtratedList.getSelectedValues()) {
			selTracks.add(new MP3Track((MP3Track)mP3Track));
		}
		getModel().getChosenTrackList().addAll(selTracks);
		
		int selIndex = chosenList.getSelectedIndex();

                if(selIndex < 0){
			selIndex = 0;
			getModel().getChosenTrackList().get(0).setIsBeingPlayed(true);
			startTrack(getModel().getChosenTrackList().get(0));
		} else{			
			if(worker == null || (worker.getState().equals(SwingWorker.StateValue.DONE))){
				((MP3Track)chosenList.getSelectedValue()).setIsBeingPlayed(true);
				startTrack((MP3Track)chosenList.getSelectedValue());				
			}
		}
		chosenList.setModel(new MP3ListModel(getModel().getChosenTrackList()));
                chosenList.setSelectedIndex(selIndex);

	}
	private void upButtonActionPerformed(){
		List<MP3Track> tmpList = getModel().getChosenTrackList();
		int selIndex = chosenList.getSelectedIndex();
		if(tmpList.size() < 2 || selIndex < 1){
			return;
		}
		
		MP3Track track = tmpList.remove(selIndex);
		tmpList.add(selIndex - 1, track);

		getModel().setChosenTrackList(tmpList);
		chosenList.setModel(new MP3ListModel(tmpList));
		chosenList.setSelectedIndex(selIndex - 1);
	}

	private void downButtonActionPerformed(){
		List<MP3Track> tmpList = getModel().getChosenTrackList();
		int selIndex = chosenList.getSelectedIndex();
		if(tmpList.size() < 2 || selIndex > tmpList.size() - 2){
			return;
		}

		MP3Track track = tmpList.remove(selIndex);
		tmpList.add(selIndex + 1, track);

		getModel().setChosenTrackList(tmpList);
		chosenList.setModel(new MP3ListModel(tmpList));
		chosenList.setSelectedIndex(selIndex + 1);
	}

	private void delButtonActionPerformed(){
		List<MP3Track> tmpList = getModel().getChosenTrackList();
		int selIndex = chosenList.getSelectedIndex();
		if(tmpList.size() < 2 || tmpList.get(selIndex).getIsBeingPlayed()){
			return;
		}
		tmpList.remove(selIndex);
		getModel().setChosenTrackList(tmpList);
		chosenList.setModel(new MP3ListModel(tmpList));
		chosenList.setSelectedIndex(0);
	}

	private void addDirsButtonActionPerformed(boolean recursively){
		if(fc == null){
			fc = new JFileChooser();
		} 
		
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int returnVal = fc.showDialog(this, StringMessages.FILE_CHOOSER_WINDOW_TITLE);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			addNewTracksToList(Mp3Utils.grabAllTracksFromDir(file, recursively));
		} else{
			return;
		}
	}

	private void addNewTracksToList(List<MP3Track> tracks){
		if(tracks.isEmpty()){
			Mp3Utils.showMessageDialog(this, StringMessages.NO_TRACKS_FOUND);
			return;
		}

		filterTextField.setText("");
		List<MP3Track> newTrackList = getModel().getAllTrackList();
		int added = 0;
		int refused = 0;
		for (MP3Track track : tracks) {
			if(!Mp3Utils.containTrack(getModel().getAllTrackList(), track.getVisibleName())){
				newTrackList.add(track);
				added++;
			} else{
				refused++;
			}
		}
		Mp3Utils.showMessageDialog(this, StringMessages.ADDED_MP3_v1 + added + StringMessages.ADDED_MP3_v2 + refused + StringMessages.ADDED_MP3_v3);
		
		getModel().setAllTrackList(newTrackList);
		getModel().setFiltratedTrackList(newTrackList);
		filtratedList.setModel(new MP3ListModel(getModel().getAllTrackList()));
	}
	
	
	
	private void startTrack(MP3Track track){
		durationInSeconds = Mp3Utils.getTrackDurationInSeconds(track.getPath());
		descriptionLabel.setText(Mp3Utils.getTrackInfo(track.getPath()));
		progressBar.setMaximum(durationInSeconds);
        secondsPast = 0;
		totalTime = Mp3Utils.countMinutes(durationInSeconds);
		stopWorker = false;

		mp3 = new MP3(track.getPath());
        mp3.play();
		startWorker();
	}
	
	private void stopTrack(){
		stopWorker = true;

	}
	private void closeButtonActionPerformed(){
		ConfirmDialog dlg = new ConfirmDialog(this, true);
		dlg.setVisible(true);
		if(dlg.chosenOption == JOptionPane.YES_OPTION){
			stopPlayer();
			startExplorer();
			doFileListSerialization();
			System.exit(0);
		}
	}
	private void doFileListSerialization(){
		if(!getModel().getAllTrackList().isEmpty()){
			FileOutputStream fos = null;
			try {
				fos = new FileOutputStream(SERIALIZE_PATH);
				for (MP3Track track : getModel().getAllTrackList()) {
					fos.write((track.getPath() + "\n").getBytes());
				}
				fos.write(("CHOSEN_TRACK_LIST" + "\n").getBytes());
				for (MP3Track track : getModel().getChosenTrackList()) {
					fos.write((track.getPath() + "\n").getBytes());
				}

			} 
			catch (IOException ex) {}
			finally{
				if(fos != null){
					try {
						fos.close();
					} catch (IOException ex) {}
				}
			}
		}
	}

	private List<MP3Track> readSerializedAllTrackList(){
		File f = new File(SERIALIZE_PATH);
		List<MP3Track> list = new ArrayList<MP3Track>();
		if(f.exists()){
			BufferedReader fr = null;
			try {
				fr = new BufferedReader(new FileReader(f));
				String mp3Path = "";
				while((mp3Path = fr.readLine()) != null){
					if(mp3Path.equals("CHOSEN_TRACK_LIST")){
						break;
					}
					int end = mp3Path.indexOf(".mp3");
					if(end == -1){
						end = mp3Path.indexOf(".MP3");
					}
					int start1 = mp3Path.lastIndexOf("/");
					int start2 = mp3Path.lastIndexOf("\\");
					int start = (start1 > start2)? start1 + 1 : start2 + 1;
					if(new File(mp3Path).exists()){
						list.add(new MP3Track(mp3Path, mp3Path.substring(start, end )));
					}
				}
			} catch (IOException ex) {}
			finally{
				if(fr != null){
					try {
						fr.close();
					} catch (IOException ex) {}
				}
			}
		}
		return list;
	}
	
	private List<MP3Track> readSerializedChosenTrackList(){
		File f = new File(SERIALIZE_PATH);
		List<MP3Track> list = new ArrayList<MP3Track>();
		boolean readTrack = false;
		if(f.exists()){
			try {
				BufferedReader fr = new BufferedReader(new FileReader(f));
				String mp3Path = "";
				while((mp3Path = fr.readLine()) != null){
					if(readTrack){
						int end = mp3Path.indexOf(".mp3");
						if(end == -1){
							end = mp3Path.indexOf(".MP3");
						}
						int start1 = mp3Path.lastIndexOf("/");
						int start2 = mp3Path.lastIndexOf("\\");
						int start = (start1 > start2)? start1 + 1 : start2 + 1;
						if(new File(mp3Path).exists()){
							list.add(new MP3Track(mp3Path, mp3Path.substring(start, end )));
						}
					}

					if(mp3Path.equals("CHOSEN_TRACK_LIST")){
						readTrack = true;
					}
				}
			} catch (IOException ex) {}
		}
		return list;
	}
	
	private void stopPlayer(){
		if(mp3 != null){
			mp3.close();
		}
	}
	public void startWorker() {
		worker = new SwingWorker<Void, Integer>() {
            @Override
            protected Void doInBackground() throws Exception {
                stopWorker = false;
                for(int i=0; i<durationInSeconds; i++) {
                    publish(i);

                    if(stopWorker) {
                        break;
                    }

                    try {
                        Thread.sleep(1000);
                    } catch(InterruptedException e) { }
					if(i == durationInSeconds - 1){
						playNextTrackAutomatically = true;
					}
                }
				workerStopped = true;
                return null;
            }

            @Override
            protected void process(List<Integer> chunks) {
                for(Integer i: chunks) {
					if(!stopWorker){
						progressBar.setValue(i);
						int procent = (i * 100/ progressBar.getMaximum()) ;
						setProgressLabelText(procent);
						timeLabel.setText(Mp3Utils.countMinutes(secondsPast) + " / " + totalTime);
						secondsPast++;
					}                    
                }
            }

            @Override
            protected void done() {
                //clear();
				if(playNextTrackAutomatically){
					endTrack();
					playNextTrackAutomatically = false;
				}
				
            }

        };
        worker.execute();
    }

	private void stopWorker(){
		if(worker != null && (worker.getState().equals(SwingWorker.StateValue.PENDING) || worker.getState().equals(SwingWorker.StateValue.STARTED))){
			workerStopped = false;
		} else {
			workerStopped = true;
		}

		playNextTrackAutomatically = false;
		stopTrack();
		stopPlayer();

		while(!workerStopped){} // czekam az aktualnie dzialajacy watek workera sie zakonczy
	}

	private void endTrack(){
		stopWorker = false;
		stopPlayer();

		int selIndex = 0;
		for (int i = 0; i < getModel().getChosenTrackList().size(); i++) {
			if(getModel().getChosenTrackList().get(i).getIsBeingPlayed()){
				selIndex = i;
			}
		}
		getModel().getChosenTrackList().get(selIndex).setIsBeingPlayed(false);
		MP3Track nextTrack = null;
			if(selIndex == getModel().getChosenTrackList().size() - 1){
				getModel().getChosenTrackList().get(0).setIsBeingPlayed(true);
				nextTrack = getModel().getChosenTrackList().get(0);
				chosenList.setSelectedIndex(0);
			} else{
				getModel().getChosenTrackList().get(selIndex + 1).setIsBeingPlayed(true);
				nextTrack = getModel().getChosenTrackList().get(selIndex + 1);
				chosenList.setSelectedIndex(selIndex + 1);
			}

		startTrack(nextTrack);
	}

	private void setProgressLabelText(int percent){
		progressLabel.setText("(" + percent + "%)");
	}

	public MP3Model getModel() {
		if(model == null){
			model = new MP3Model();
		}
		return model;
	}


	public class ChosenListCellRenderer implements ListCellRenderer{
		private JLabel renderer = new JLabel();

		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
			if(value instanceof MP3Track){
				MP3Track track = (MP3Track)value;
				if(track.getIsBeingPlayed()){
					renderer.setText("<html><b> ----- " + track.getVisibleName() + " ----- </b></html>");
					renderer.setForeground(Color.WHITE);
				} else{
					renderer.setText("<html>" + track.getVisibleName() + "</html>");
					renderer.setForeground(Color.LIGHT_GRAY);
				}
				if(isSelected){
					renderer.setBackground(new Color(58, 57, 50));
				} else{
					renderer.setBackground(new Color(76, 74, 65));
				}
			} else {
				renderer.setText("");
			}

			renderer.setOpaque(true);
			return renderer;
		}

	}
	
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
				try { //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
					UIManager.setLookAndFeel("org.pushingpixels.substance.api.skin.SubstanceTwilightLookAndFeel");
				} catch (Exception e){
					e.printStackTrace();
				}
				PlayerFrame pf = new PlayerFrame();
				pf.setLocationRelativeTo(null);
                pf.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JButton addDirsButton;
    private javax.swing.JButton addDirsRecursivelyButton;
    private javax.swing.JList chosenList;
    private javax.swing.JButton clearButton;
    private javax.swing.JButton closeButton;
    private javax.swing.JButton delButton;
    private javax.swing.JLabel descriptionLabel;
    private javax.swing.JButton downButton;
    private javax.swing.JTextField filterTextField;
    private javax.swing.JList filtratedList;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel10;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private org.jdesktop.swingx.JXImagePanel jXImagePanel1;
    private javax.swing.JLabel playTimeLabel;
    private javax.swing.JLabel playlistLabel;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel progressLabel;
    private javax.swing.JButton stopButton;
    private javax.swing.JLabel timeLabel;
    private javax.swing.JLabel titleLabel;
    private javax.swing.JButton upButton;
    // End of variables declaration//GEN-END:variables

}
